const fs = require('fs');
const path = require('path');
const { parseSubpkgConfig, validateSubpkgConfig } = require('../utils/config-parser');

/**
 * 获取当前文件所属的子包名称
 * @param {string} filePath 文件路径
 * @param {string} subpkgRoot 子包根目录
 * @returns {string|null} 子包名称
 */
function getSubpkgName(filePath, subpkgRoot) {
  const relativePath = path.relative(subpkgRoot, filePath);
  const parts = relativePath.split(path.sep);
  return parts[0];
}

/**
 * 从导入语句中提取子包名称
 * @param {string} importPath 导入路径
 * @returns {string|null} 子包名称
 */
function extractSubpkgFromImport(importPath) {
  // 匹配 "Subpkg/SubpkgName/..." 格式的导入
  const subpkgMatch = importPath.match(/^Subpkg\/([^\/]+)/);
  if (subpkgMatch) {
    return subpkgMatch[1];
  }
  return null;
}

/**
 * 获取所有可用的子包列表
 * @param {string} subpkgRoot 子包根目录
 * @returns {string[]} 子包名称列表
 */
function getAllSubpkgs(subpkgRoot) {
  try {
    const items = fs.readdirSync(subpkgRoot);
    return items.filter(item => {
      const itemPath = path.join(subpkgRoot, item);
      return fs.statSync(itemPath).isDirectory() && 
             validateSubpkgConfig(path.join(itemPath, 'Config.ts'));
    });
  } catch (error) {
    console.warn(`无法读取子包目录: ${subpkgRoot}`, error.message);
    return [];
  }
}

/**
 * 检查是否为有效的子包导入路径
 * @param {string} importPath 导入路径
 * @param {string} subpkgRoot 子包根目录
 * @returns {boolean} 是否为有效的子包导入
 */
function isValidSubpkgImport(importPath, subpkgRoot) {
  const subpkgName = extractSubpkgFromImport(importPath);
  if (!subpkgName) {
    return false;
  }
  
  const subpkgPath = path.join(subpkgRoot, subpkgName);
  return fs.existsSync(subpkgPath) && 
         fs.statSync(subpkgPath).isDirectory() &&
         validateSubpkgConfig(path.join(subpkgPath, 'Config.ts'));
}

/**
 * 检查导入是否为“子包根目录下的ts文件”。
 * 允许形式：Subpkg/<SubpkgName>/<File> 或 Subpkg/<SubpkgName>/<File>.ts
 * @param {string} importPath 导入路径
 * @param {string} subpkgRoot 子包根目录
 * @returns {boolean}
 */
function isImportingSubpkgRootTsFile(importPath, subpkgRoot) {
  const match = importPath.match(/^Subpkg\/([^\/]+)\/([^\/]+)(?:\.ts)?$/);
  if (!match) {
    return false;
  }
  const subpkgName = match[1];
  const fileBaseName = match[2];
  const filePathWithExt = path.join(subpkgRoot, subpkgName, `${fileBaseName}.ts`);
  try {
    return fs.existsSync(filePathWithExt) && fs.statSync(filePathWithExt).isFile();
  } catch (e) {
    return false;
  }
}

/**
 * 判断当前文件是否为“子包根目录下的 .ts 文件”。
 * 形如：<subpkgRoot>/<SubpkgName>/<File>.ts
 * @param {string} filePath
 * @param {string} subpkgRoot
 * @returns {boolean}
 */
function isCurrentFileSubpkgRootTs(filePath, subpkgRoot) {
  const relative = path.relative(subpkgRoot, filePath);
  if (relative.startsWith('..') || relative === filePath) return false;
  const parts = relative.split(path.sep);
  return parts.length === 2 && parts[0] && parts[1].endsWith('.ts');
}

/**
 * 是否为子包内“更深层”的导入（非子包根目录文件）。
 * 形如：Subpkg/<SubpkgName>/<dir>/<...>
 * @param {string} importPath
 * @returns {boolean}
 */
function isImportingNestedSubpkgFile(importPath) {
  return /^Subpkg\/[^\/]+\/[^\/]+\//.test(importPath);
}

/**
 * 检查文件是否在Subpkg目录内
 * @param {string} filePath 文件路径
 * @param {string} subpkgRoot 子包根目录
 * @returns {boolean} 是否在Subpkg目录内
 */
function isInSubpkgDirectory(filePath, subpkgRoot) {
  const relativePath = path.relative(subpkgRoot, filePath);
  return !relativePath.startsWith('..') && relativePath !== filePath;
}

module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: '检查子包依赖关系，确保只导入已配置的子包',
      category: 'Best Practices',
      recommended: true,
    },
    fixable: null,
    schema: [
      {
        type: 'object',
        properties: {
          subpkgRoot: {
            type: 'string',
            description: '子包根目录路径，相对于项目根目录'
          },
          ignorePatterns: {
            type: 'array',
            items: {
              type: 'string'
            },
            description: '忽略的文件模式'
          }
        },
        additionalProperties: false
      }
    ],
    messages: {
      invalidSubpkgImport: '子包 "{{currentSubpkg}}" 不允许导入子包 "{{importedSubpkg}}"，请优先考虑懒加载对应子包后动态导入，只有当确实有必要时才在Config.ts的scriptDeps中配置依赖关系',
      invalidSubpkgPath: '无效的子包路径 "{{importedSubpkg}}"，请检查子包是否存在',
      missingConfig: '子包 "{{currentSubpkg}}" 缺少Config.ts配置文件',
      rootStaticImportForbidden: '子包根目录的ts文件不允许静态导入子包内文件："{{importPath}}"，请改为懒加载对应子包后动态导入或调整结构'
    }
  },

  create(context) {
    const options = context.options[0] || {};
    const subpkgRoot = options.subpkgRoot || 'cc3x-server/assets/Subpkg';
    const ignorePatterns = options.ignorePatterns || [];
    const projectRoot = context.getCwd();
    const fullSubpkgRoot = path.resolve(projectRoot, subpkgRoot);
    
    // 缓存子包配置
    const subpkgConfigs = new Map();
    const allSubpkgs = getAllSubpkgs(fullSubpkgRoot);

    /**
     * 检查文件是否应该被忽略
     * @param {string} filePath 文件路径
     * @returns {boolean} 是否应该忽略
     */
    function shouldIgnoreFile(filePath) {
      return ignorePatterns.some(pattern => {
        const regex = new RegExp(pattern);
        return regex.test(filePath);
      });
    }

    /**
     * 获取子包的依赖配置
     * @param {string} subpkgName 子包名称
     * @returns {string[]} 依赖列表
     */
    function getSubpkgDeps(subpkgName) {
      if (subpkgConfigs.has(subpkgName)) {
        return subpkgConfigs.get(subpkgName);
      }

      const configPath = path.join(fullSubpkgRoot, subpkgName, 'Config.ts');
      
      if (!fs.existsSync(configPath)) {
        context.report({
          node: context.getSourceCode().ast,
          messageId: 'missingConfig',
          data: {
            currentSubpkg: subpkgName
          }
        });
        return [];
      }

      const deps = parseSubpkgConfig(configPath);
      subpkgConfigs.set(subpkgName, deps);
      return deps;
    }

    return {
      ImportDeclaration(node) {
        const importPath = node.source.value;
        const currentFilePath = context.getFilename();
        
        // 只检查Subpkg目录内的文件
        if (!isInSubpkgDirectory(currentFilePath, fullSubpkgRoot)) {
          return;
        }
        
        // 检查是否应该忽略此文件
        if (shouldIgnoreFile(currentFilePath)) {
          return;
        }

        const importedSubpkg = extractSubpkgFromImport(importPath);
        
        if (!importedSubpkg) {
          return; // 不是子包导入
        }

        const currentSubpkg = getSubpkgName(currentFilePath, fullSubpkgRoot);
        
        if (!currentSubpkg) {
          return; // 当前文件不在子包中
        }

        // 若当前文件是子包根目录的 .ts 文件，则禁止静态导入子包内“更深层”的文件
        if (isCurrentFileSubpkgRootTs(currentFilePath, fullSubpkgRoot)) {
          // 允许导入任意子包根目录的 .ts 文件
          if (isImportingSubpkgRootTsFile(importPath, fullSubpkgRoot)) {
            return;
          }
          // 只要是子包内的更深层导入，一律禁止
          if (isImportingNestedSubpkgFile(importPath)) {
            context.report({
              node: node.source,
              messageId: 'rootStaticImportForbidden',
              data: { importPath }
            });
            return;
          }
        }

        // 允许导入当前子包内的其他文件（但上述根目录静态导入限制已优先处理）
        if (importedSubpkg === currentSubpkg) {
          return;
        }

        // 检查导入的子包是否存在
        if (!isValidSubpkgImport(importPath, fullSubpkgRoot)) {
          context.report({
            node: node.source,
            messageId: 'invalidSubpkgPath',
            data: {
              importedSubpkg
            }
          });
          return;
        }

        // 允许导入子包根目录的ts文件
        if (isImportingSubpkgRootTsFile(importPath, fullSubpkgRoot)) {
          return;
        }

        // 检查是否在允许的依赖列表中
        const allowedDeps = getSubpkgDeps(currentSubpkg);
        
        if (!allowedDeps.includes(importedSubpkg)) {
          context.report({
            node: node.source,
            messageId: 'invalidSubpkgImport',
            data: {
              currentSubpkg,
              importedSubpkg
            }
          });
        }
      },

      CallExpression(node) {
        // 检查动态导入
        if (node.callee.type === 'Import' && node.arguments.length > 0) {
          const importPath = node.arguments[0];
          if (importPath.type === 'Literal' && typeof importPath.value === 'string') {
            const currentFilePath = context.getFilename();
            
            // 只检查Subpkg目录内的文件
            if (!isInSubpkgDirectory(currentFilePath, fullSubpkgRoot)) {
              return;
            }
            
            // 检查是否应该忽略此文件
            if (shouldIgnoreFile(currentFilePath)) {
              return;
            }

            const importedSubpkg = extractSubpkgFromImport(importPath.value);
            
            if (!importedSubpkg) {
              return; // 不是子包导入
            }

            const currentSubpkg = getSubpkgName(currentFilePath, fullSubpkgRoot);
            
            if (!currentSubpkg) {
              return; // 当前文件不在子包中
            }

            // 允许导入当前子包内的其他文件
            if (importedSubpkg === currentSubpkg) {
              return;
            }

            // 检查导入的子包是否存在
            if (!isValidSubpkgImport(importPath.value, fullSubpkgRoot)) {
              context.report({
                node: importPath,
                messageId: 'invalidSubpkgPath',
                data: {
                  importedSubpkg
                }
              });
              return;
            }

            // 允许导入子包根目录的ts文件
            if (isImportingSubpkgRootTsFile(importPath.value, fullSubpkgRoot)) {
              return;
            }

            // 检查是否在允许的依赖列表中
            const allowedDeps = getSubpkgDeps(currentSubpkg);
            
            if (!allowedDeps.includes(importedSubpkg)) {
              context.report({
                node: importPath,
                messageId: 'invalidSubpkgImport',
                data: {
                  currentSubpkg,
                  importedSubpkg
                }
              });
            }
          }
        }
      }
    };
  }
}; 
